package net.mikoo.seals.biz.service.impl;

import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;

import net.mikoo.seals.biz.common.BaseServices;
import net.mikoo.seals.biz.mapper.CustosMapper;
import net.mikoo.seals.biz.mapper.DevicesMapper;
import net.mikoo.seals.biz.mapper.PartyMapper;
import net.mikoo.seals.biz.mapper.PersonMapper;
import net.mikoo.seals.biz.mapper.SealMapper;
import net.mikoo.seals.biz.mapper.StaffMapper;
import net.mikoo.seals.biz.service.SealServices;
import net.mikoo.seals.common.enums.CustosStatusEnum;
import net.mikoo.seals.common.enums.CustosTypeEnum;
import net.mikoo.seals.common.enums.DevicesStatusEnum;
import net.mikoo.seals.common.enums.SealStatusEnum;
import net.mikoo.seals.common.exception.DataNotFoundException;
import net.mikoo.seals.common.exception.ParametersException;
import net.mikoo.seals.common.model.PageModel;
import net.mikoo.seals.model.Custos;
import net.mikoo.seals.model.CustosQuery;
import net.mikoo.seals.model.Devices;
import net.mikoo.seals.model.DevicesQuery;
import net.mikoo.seals.model.Party;
import net.mikoo.seals.model.Person;
import net.mikoo.seals.model.Seal;
import net.mikoo.seals.model.SealQuery;
import net.mikoo.seals.model.Staff;
import net.mikoo.seals.model.StaffQuery;

@Service
public class SealServicesImpl extends BaseServices implements SealServices {
	
	Logger logger = LoggerFactory.getLogger(SealServicesImpl.class);

	@Autowired
	private SealMapper sealMapper;
	
	@Autowired
	private PartyMapper partyMapper;
	
	@Autowired
	private DevicesMapper devicesMapper;
	
	@Autowired
	private CustosMapper custosMapper;
	
	@Autowired
	private StaffMapper	staffMapper;
	
	@Autowired
	private PersonMapper personMapper;
	
	@Override
	public void save(Seal seal) {
		
		if(seal == null){
			throw new ParametersException("seal is null!");
		}
		
		if(StringUtils.isBlank(seal.getSealName())) {
			throw new ParametersException("印章名称不能为空");
		}
		
		if(seal.getPartyId() == null) {
			throw new ParametersException("印章管理员不能为空");
		}
		
		if(seal.getCompanyId() == null) {
			throw new ParametersException("印章管理员不能为空");
		}
		
		
		
		if(seal.getLimitUrgentApply() == null) {
			throw new ParametersException("请输入紧急申请次数");
		}
		
		Party party = partyMapper.selectByPrimaryKey(seal.getPartyId());
		if(party == null) {
			throw new DataNotFoundException("保管员信息不存在");
		}
		
//		if(!seal.getCompanyId().equals(party.getCompanyId())) {
//			throw new DataNotFoundException("保管员不是公司员工，无法设置");
//		}
		StaffQuery query = new StaffQuery();
		query.setCompanyId(seal.getCompanyId());
		query.setPartyId(seal.getPartyId());
		Staff staff = staffMapper.selectInfoByQuery(query);
		if(staff == null) {
			throw new ParametersException("保管员不是公司员工，无法设置");
		}
		
		if(StringUtils.isBlank(seal.getIsForcedPhoto())) {
			seal.setIsForcedPhoto("N");
		}
		
		this.transactionTemplate.execute(new TransactionCallbackWithoutResult() {
			
			@Override
			protected void doInTransactionWithoutResult(TransactionStatus status) {
				try {
					
					seal.setCustosName(party.getPerson().getName());
					seal.setQuantity(0);
					seal.setApplyTimes(0);
					seal.setUseTimes(0);
					seal.setSealStatus(SealStatusEnum.DISABLE.getCode());
					seal.setCreateTime(new Date());
					sealMapper.insert(seal);
					
					Custos custos = new Custos();
					custos.setCustosType(CustosTypeEnum.CUSTOS.code());
					custos.setCompanyId(seal.getCompanyId());
					custos.setSealId(seal.getSealId());
					custos.setPartyId(seal.getPartyId());
					custos.setUserLoginId(party.getUserLoginId());
					custos.setCreateTime(new Date());
					custos.setCustosStatus(CustosStatusEnum.EFFECTIVE.code());
					custosMapper.insert(custos);
				} catch (Exception e) {
					status.setRollbackOnly();
					throw e;
				}
			}
		});
	}

	@Override
	public void modify(Seal seal) {
		if(seal == null || seal.getSealId() == null){
			throw new ParametersException("seal is null!");
		}
		
		if(seal.getSealId() == null) {
			throw new ParametersException("SealId is null!");
		}
		
		if(seal.getCompanyId() == null) {
			throw new ParametersException("CompanyId is null!");
		}
		
		
		if(StringUtils.isBlank(seal.getSealName())) {
			throw new ParametersException("请输入印章名称");
		}
		
		if(seal.getPartyId() == null) {
			throw new ParametersException("请选择保管员");
		}
		
		if(seal.getLimitUrgentApply() == null) {
			throw new ParametersException("请输入紧急申请次数");
		}
		
		if(StringUtils.isBlank(seal.getIsForcedPhoto())) {
			seal.setIsForcedPhoto("N");
		}
		
		Party party = partyMapper.selectByPrimaryKey(seal.getPartyId());
		
		if(party == null) {
			throw new ParametersException("保管员信息不存在");
		}
		
		seal.setCustosName(party.getPerson().getName());
		
		this.transactionTemplate.execute(new TransactionCallbackWithoutResult() {
			
			@Override
			protected void doInTransactionWithoutResult(TransactionStatus status) {
				try {
					
					sealMapper.update(seal);
					
					CustosQuery query =new CustosQuery();
					query.setCompanyId(seal.getCompanyId());
					query.setSealId(seal.getSealId());
					query.setPartyId(seal.getPartyId());
					//Custos exits = custosMapper.selectInfoByQuery(query);
					
					Custos custos = new Custos();
					custos.setCompanyId(seal.getCompanyId());
					custos.setSealId(seal.getSealId());
					custos.setPartyId(seal.getPartyId());
					custos.setUserLoginId(party.getUserLoginId());
					custos.setCreateTime(new Date());
					custosMapper.insert(custos);
					
				} catch (Exception e) {
					status.setRollbackOnly();
					throw e;
				}
			}
		});
		
	}
	
	@Override
	public Seal getInfoById(Long SealId) {
		if(SealId == null){
			throw new ParametersException("SealId is null!");
		}
		
		Seal Seal = sealMapper.selectInfoById(SealId);
		return Seal;
	}
	
	
	
	@Override
	public PageModel<Seal> getPageByQuery(SealQuery query) {
		
		
		List<Seal> datas = sealMapper.selectPageByQuery(query);
		Integer total = sealMapper.countPageByQuery(query);
		PageModel<Seal> pm = new PageModel<Seal>(total,datas);
		return pm;
	}
	

	@Override
	public Seal getInfoByQuery(SealQuery query) {
		if(query == null){
			throw new ParametersException("query is null!");
		}
		
		if(query.getSealId() == null){
			throw new ParametersException("SealId is null!");
		}
		
		if(query.getCompanyId() == null){
			throw new ParametersException("CompanyId is null!");
		}
		
		Seal seal = sealMapper.selectInfoByQuery(query);
		
		if(seal != null && seal.getInterimPartyId() != null) {
			Person person = personMapper.selectByPartyId(seal.getInterimPartyId());
			if(person != null) {
				seal.setInterimPartyName(person.getName());
			}
			
		}
		return seal;
	}

	@Override
	public void changeStatus(Seal seal) {
		
		if(seal == null) {
			throw new ParametersException("seal is null");
		}
		
		if(seal.getSealId() == null) {
			throw new ParametersException("sealId is null");
		}
		
		if(seal.getCompanyId() == null) {
			throw new ParametersException("companyId is null");
		}
		
		
		Seal exist = sealMapper.selectInfoById(seal.getSealId());
		if(!seal.getCompanyId().equals(exist.getCompanyId())) {
			throw new ParametersException("您无权操作此印章");
		}
		
		if(exist.getSealStatus().equals(SealStatusEnum.DISABLE.code())) {
			
			DevicesQuery query = new DevicesQuery();
			query.setCompanyId(seal.getCompanyId());
			query.setSealId(seal.getSealId());
			query.setDevicesStatus(DevicesStatusEnum.ACTIVATE.code());
			List<Devices> devices = devicesMapper.selectListByQuery(query);
			
			if(devices == null || devices.isEmpty()) {
				throw new ParametersException("印章无可用设备，请先启用设备");
			}
			
			seal.setSealStatus(SealStatusEnum.ENABLE.code());
		}else {
			seal.setSealStatus(SealStatusEnum.DISABLE.code());
		}
		
		Integer num = sealMapper.updateStatus(seal);
		
		if(num==null || num == 0) {
			throw new ParametersException("印章状态更新失败");
		}
		
	}

	@Override
	public void bindingDevices(Devices devices) {
		if(devices == null) {
			throw new ParametersException("devices");
		}
		
		if(devices.getCompanyId() == null) {
			throw new ParametersException("CompanyId is null");
		}
		
		if(devices.getSealId() == null) {
			throw new ParametersException("sealid is null");
		}
		
		if(devices.getDevicesId() == null) {
			throw new ParametersException("请选择绑定设备");
		}
		
		
		Devices existDevices = devicesMapper.selectInfoById(devices.getDevicesId());
		if(existDevices == null) {
			throw new ParametersException("设备信息不存在");
		}
		
		if(!existDevices.getCompanyId().equals(devices.getCompanyId())) {
			throw new ParametersException("您无权操作此设备");
		}
		
		if(!existDevices.getDevicesStatus().equals(DevicesStatusEnum.WAIT_BIND.code()) ) {
			throw new ParametersException("设备已添加");
		}
		
		existDevices.setSealId(devices.getSealId());
		existDevices.setDevicesStatus(DevicesStatusEnum.WAIT_INSTALL.code());
		existDevices.setAlias(devices.getAlias());
		existDevices.setBindingTime(new Date());
		devicesMapper.update(existDevices);
		
	}

	@Override
	public List<Seal> getListByQuery(SealQuery query) {
		if(query == null) {
			throw new ParametersException("query is null");
		}
		
		if(query.getCompanyId() == null) {
			throw new ParametersException("CompanyId is null");
		}
		
		
		List<Seal> seals = sealMapper.selectListByQuery(query);
		
		return seals;
	}
	
}